import { css } from "@emotion/react"
import { LoginPasswordForm } from "../data"
import { useMemo, useRef, useState } from "react"
import { motion } from "motion/react"
import styled from "@emotion/styled"
import Svg, { SvgComponent } from "@/components/base/Svg"
import { createLogger } from "@/utils/logger"

const CurrentForm = LoginPasswordForm
const logger = createLogger("PhoneInputFormItem")

const Container = styled(motion.div)`
    display: flex;
    flex-direction: row;
    gap: 1rem;
    border-radius: 8rem;
    background-color: #f3f3f7;
`
const ClearButton = styled(SvgComponent("login_page_v2/clear.svg"))`
    width: auto;
    height: 100%;
`

// 允許 8 - 20 個字元，必須包含英文字母、數字
const PasswordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,20}$/

type Props = Omit<ExtractStyledProps<typeof Container>, "children">
export default function PasswordInputFormItem({ ...props }: Props) {
    const {
        //
        className: _className,
        style: _style,
        css: _css,
        ...rest
    } = props
    const [focused, setFocused] = useState(false)
    const form = CurrentForm.useFormContext()
    const focusedOrHasValue = form.watch("password") || focused
    const inputRef = useRef<HTMLInputElement>(null)

    const [passwordVisible, setPasswordVisible] = useState(false)

    const errorMessage = [
        //
        form.formState.errors.password?.message,
    ]
        .filter(Boolean)
        .shift()

    const showErrorMessage = useMemo(() => {
        return errorMessage
    }, [errorMessage])

    const boxShadow = useMemo(() => {
        if (showErrorMessage) {
            return "0 0 1rem 1rem #cc0033 inset"
        }
        if (!form.formState.errors.number && focusedOrHasValue && form.formState.isValid) {
            return "0 0 1rem 1rem #00c52b inset"
        }
        if (focusedOrHasValue) {
            return "0 0 1rem 1rem #165dff inset"
        }
        return "0 0 1rem 1rem #b8bdcc inset"
    }, [focusedOrHasValue, form.formState.errors.number, form.formState.isValid, showErrorMessage])

    return (
        <CurrentForm.ErrorWrapper
            css={css`
                display: flex;
                flex-direction: column;
                gap: 8rem;
                align-items: stretch;
            `}
            field="number"
            render={() => {
                return (
                    <motion.caption
                        initial={{
                            opacity: 0,
                        }}
                        animate={{
                            opacity: showErrorMessage ? 1 : 0,
                        }}
                        css={css`
                            color: #cc0033;
                            align-self: flex-start;
                            display: flex;
                            flex-direction: row;
                            gap: 4rem;
                            align-items: center;
                            font-size: 12rem;
                            line-height: 16rem;
                            font-weight: 500;
                            font-family: "Gilroy", monospace;
                            min-height: 20rem;
                        `}
                    >
                        <Svg
                            css={css`
                                min-width: 16rem;
                                min-height: 16rem;
                            `}
                            src="login/error_head.svg"
                        />
                        {errorMessage}
                    </motion.caption>
                )
            }}
        >
            <Container
                style={{
                    ..._style,
                }}
                initial={{
                    boxShadow: "0 0 1rem 1rem #b8bdcc inset",
                }}
                animate={{
                    boxShadow,
                }}
                css={css`
                    position: relative;
                    display: flex;
                    flex-direction: row;
                    gap: 1rem;
                    border-radius: 8rem;
                    background-color: #f3f3f7;
                    height: 56rem;
                    justify-content: center;
                    align-items: center;
                    padding: 0 16rem;
                    cursor: text;

                    > input,
                    > select {
                        border: none;
                        font-size: 16rem;
                        line-height: 24rem;
                        font-weight: 500;
                        color: #3e4046;
                        font-family: "Gilroy", monospace;
                        box-sizing: border-box;
                        /* disable input default style */
                        outline: none;
                        background-color: transparent;
                        &:focus {
                            outline: none;
                        }
                        &::placeholder {
                            color: #9ca3b4;
                        }
                    }
                `}
                className={_className}
                onClick={() => {
                    inputRef.current?.focus()
                }}
            >
                <motion.div
                    css={css`
                        position: absolute;
                        top: 8rem;
                        left: 16rem;
                        font-size: 12rem;
                        line-height: 16rem;
                        font-weight: 500;
                        font-family: "Gilroy", monospace;
                        color: #6a7081;
                    `}
                    initial={{ opacity: 0 }}
                    animate={{ opacity: focusedOrHasValue ? 1 : 0 }}
                >
                    Password
                </motion.div>
                <CurrentForm.BaseItem
                    label="Password"
                    field="password"
                    options={{
                        validate: (value) => {
                            if (value.length === 0) {
                                return "Password is required"
                            }
                            if (value.length < 8) {
                                return "Password should be at least 8 characters"
                            }
                            if (!PasswordRegex.test(value)) {
                                return "Invalid password, only allow 8-20 characters, including letters and numbers"
                            }
                            return true
                        },
                    }}
                    render={({ methods }) => {
                        const password = methods.watch("password")
                        const passwordLength = (() => {
                            if (password.length < 8) {
                                return 8
                            }
                            return 20
                        })()

                        const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
                            methods.setValue("password", e.target.value)
                            methods.trigger("password")
                        }

                        return (
                            <motion.input
                                initial={{
                                    opacity: 1,
                                    marginTop: "auto",
                                    marginBottom: "16rem",
                                }}
                                ref={inputRef}
                                css={css`
                                    flex: 1;
                                    caret-color: #1e71ff;
                                    margin: auto;
                                    user-select: none;
                                    pointer-events: none;
                                `}
                                animate={{
                                    marginTop: focusedOrHasValue ? "auto" : "auto",
                                    marginBottom: focusedOrHasValue ? "8rem" : "16rem",
                                    opacity: focusedOrHasValue ? 1 : 0.5,
                                }}
                                onFocus={(ev) => {
                                    setFocused(true)
                                    ev.preventDefault()
                                }}
                                onBlur={() => setFocused(false)}
                                type={passwordVisible ? "text" : "password"}
                                placeholder={focused ? "" : "Password"}
                                inputMode="text"
                                maxLength={passwordLength}
                                onChange={handleChange}
                                value={methods.watch("password")}
                                autoFocus
                            />
                        )
                    }}
                />
                <motion.div
                    css={css`
                        height: 14rem;
                        position: absolute;
                        right: 16rem;
                        transform-origin: center;
                        cursor: pointer;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        gap: 16rem;
                    `}
                    initial={{
                        opacity: 0,
                        scale: 0.8,
                        visibility: "hidden",
                    }}
                    animate={{
                        opacity: form.watch("password") ? 1 : 0,
                        scale: form.watch("password") ? 1 : 0.8,
                        visibility: form.watch("password") ? "visible" : "hidden",
                    }}
                >
                    <ClearButton
                        onClick={() => {
                            form.setValue("password", "")
                            form.trigger("password")
                        }}
                    />
                    <motion.div
                        css={css`
                            width: 100%;
                            height: 100%;
                            display: flex;
                            justify-content: center;
                            align-items: center;
                            width: 16rem;
                            height: 14rem;
                        `}
                        onClick={() => {
                            setPasswordVisible((prev) => !prev)
                        }}
                    >
                        <Svg
                            src={
                                passwordVisible
                                    ? "login_page_v2/visible.svg"
                                    : "login_page_v2/invisible.svg"
                            }
                            css={css`
                                width: auto;
                                height: 100%;
                                user-select: none;
                                pointer-events: none;
                            `}
                        />
                    </motion.div>
                </motion.div>
            </Container>
        </CurrentForm.ErrorWrapper>
    )
}
